package com.pj.project.sys_user_acc;

import javax.servlet.http.HttpServletRequest;

import com.pj.project.sys_user.SysUser;
import com.pj.project.sys_user.SysUserUtil;
import com.pj.project.sys_user_sync.brd.SspServerBrdUtil;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.pj.current.config.SystemObject;
import com.pj.current.satoken.StpUserUtil;
import com.pj.project.sys_client.SysClientUtil;
import com.pj.project.sys_login_log.SysLoginLog;
import com.pj.project.sys_login_log.SysLoginLogUtil;
import com.pj.project.sys_user_password.SysUserPasswordService;
import com.pj.project4sp.config.SpConfigUtil;
import com.pj.utils.sg.AjaxError;
import com.pj.utils.sg.IpUtil;
import com.pj.utils.sg.NbUtil;
import com.pj.utils.so.SoMap;

import cn.dev33.satoken.spring.SpringMVCUtil;
import cn.dev33.satoken.util.SaFoxUtil;
import cn.hutool.core.lang.Validator;
import eu.bitwalker.useragentutils.UserAgent;

/**
 * 用户登录模块 Service
 * @author : kong
 * @date : 2020-06-26 17:17
 */
@Service
public class SysUserAccService {

    @Autowired
    SysUserAccMapper sysUserAccMapper;

    @Autowired
    SysUserPasswordService sysUserService;

    @Autowired
    WxMpService wxMpService;

    /** 根据name、password登录，登录成功返回SysUserAcc对象，登录则抛出异常 */
    public SysUserAcc doLogin(String name, String password) {

        // 1、获取user 
        SysUserAcc userAcc = null;
        
        // 如果是手机号 
        if(NbUtil.isPhone(name)) {
            userAcc = sysUserAccMapper.getByPhone(name);
        }
        // 如果是邮箱 
        else if(Validator.isEmail(name)) {
        	userAcc = sysUserAccMapper.getByEmail(name);
        }
        // 如果是账号id 
        else if(NbUtil.isNumber(name)) {
            userAcc = sysUserAccMapper.getById(Long.parseLong(name));
        }
        // 什么都不是，则当做 username 处理
        else {
            userAcc = sysUserAccMapper.getByUsername(name);
        }

        // 2、开始校验
        if(userAcc == null){
            AjaxError.throwMsg("无此账号");
        }
        if(NbUtil.isNull(userAcc.getPassword())) {
            AjaxError.throwMsg("此账号尚未设置密码，无法登陆");
        }
        String md5Password = SystemObject.getPasswordMd5(userAcc.getId(), password);
        if(userAcc.getPassword().equals(md5Password) == false){
            AjaxError.throwMsg("密码错误");
        }
        if(userAcc.getStatus() == 2) {
            AjaxError.throwMsg("此账号已被禁用，如有疑问，请联系管理员");
        }

        // 校验通过 
        return userAcc;
    }


    /** 小程序授权直接登录 */
    public SysUserAcc doLoginApplet(String name) {

        // 1、获取user
        SysUserAcc userAcc = null;

        // 如果是手机号
        if(NbUtil.isPhone(name)) {
            userAcc = sysUserAccMapper.getByPhone(name);
        }
        // 如果是邮箱
        else if(Validator.isEmail(name)) {
            userAcc = sysUserAccMapper.getByEmail(name);
        }
        // 如果是账号id
        else if(NbUtil.isNumber(name)) {
            userAcc = sysUserAccMapper.getById(Long.parseLong(name));
        }
        // 什么都不是，则当做 username 处理
        else {
            userAcc = sysUserAccMapper.getByUsername(name);
        }

        // 2、开始校验
        if(userAcc == null){
            AjaxError.throwMsg("无此账号");
        }
        /*if(NbUtil.isNull(userAcc.getPassword())) {
            AjaxError.throwMsg("此账号尚未设置密码，无法登陆");
        }*/
        if(userAcc.getStatus() == 2) {
            AjaxError.throwMsg("此账号已被禁用，如有疑问，请联系管理员");
        }

        // 校验通过
        return userAcc;
    }


    /** 微信扫码登录 */
    public SysUserAcc doLoginWechat(WxOAuth2UserInfo wxUser) {

        // 1、获取user
        SysUserAcc userAcc = null;

        userAcc = sysUserAccMapper.getByOpenId(wxUser.getOpenid());
        // 检查登录信息
        boolean isNew = false; // 此变量含义：该手机号是否为首次登录 
        // 2、开始校验
        if(userAcc == null){ //若无此账号则注册
            // 开始注册
            SysUserAcc sysUserAcc = regByWechat(wxUser);
            userAcc=sysUserAcc;
            isNew = true;
        }

        if(isNew) {
            // $$ 向外广播
            SysUser s2 = SysUserUtil.sysUserMapper.getByOpenId(wxUser.getOpenid());
            SspServerBrdUtil.userAdd(s2, s2.getPassword2());
        }

        // 注册成功返回对象
        return userAcc;
    }


    /** 微信扫码自动注册 */
    @Transactional(rollbackFor = Exception.class)
    public SysUserAcc regByWechat(WxOAuth2UserInfo wxUser) {

        // 插入数据
        SoMap so = new SoMap();
        so.set("username", wxUser.getNickname());		// 微信昵称作为账号
        so.set("avatar", wxUser.getHeadImgUrl());   	// 默认头像
        so.set("openid", wxUser.getOpenid());		// openId
        so.set("unionid", wxUser.getUnionId());		// openId
        sysUserAccMapper.saveWechat(so);

        // 再查询出来
        SysUserAcc userAcc = sysUserAccMapper.getByOpenId(wxUser.getOpenid());

        // 登录成功，返回user对象
        return userAcc;
    }


    /** 根据手机号注册 */
    @Transactional(rollbackFor = Exception.class)
    public SysUserAcc regByPhone(String phone, String openid, String unionId) {

        // 插入数据 
    	SoMap so = new SoMap();
        so.set("username", SysUserAccUtil.getKyUsername("p" + phone));		// 随机昵称 
        so.set("avatar", SpConfigUtil.userDefaultAvatar());   	// 默认头像
        so.set("phone", phone);		// 创建时间 
        so.set("openid", openid);		// 微信openid
        so.set("unionId", unionId);		// 微信unionId

        sysUserAccMapper.save(so);

        // 再查询出来 
        SysUserAcc userAcc = sysUserAccMapper.getByPhone(phone);

        // 修改密码 
//        if(NbUtil.isNull(password)) {
//            sysUserService.updatePassword(userAcc.getId(), password);
//        }
        
        // 登录成功，返回user对象 
        return userAcc;
    }

    /**
     * 登录成功后，更新最后登录时间、IP、次数等信息
     */
    public void successLogin(long userId, String redirect) {
    	// 裁剪掉 redirect 的参数部分 
    	if(SaFoxUtil.isNotEmpty(redirect) && redirect.indexOf("?") != -1) {
			int index = redirect.indexOf("?");
			redirect = redirect.substring(0, index);
		}
    	
    	// 更新User表记录  
    	HttpServletRequest request = SpringMVCUtil.getRequest();
		UserAgent ua = UserAgent.parseUserAgentString(request.getHeader("user-agent"));
        String loginIp = IpUtil.getIP(request);
        
        int line = sysUserAccMapper.successLogin(userId, loginIp);
        AjaxError.notLine(line, "登录记录更新失败");
        
        // 更新登录日志表记录 
        SysLoginLog s = new SysLoginLog();	// 声明对象 
		s.setUserId(userId);			// 用户id 
		s.setAccToken(StpUserUtil.getTokenValue());		// 本次登录Token 
		s.setLoginIp(loginIp);			// 登陆IP 
		s.setLoginAddress(IpUtil.getAddres(loginIp));	// 登陆地
		s.setLoginDevice(ua.getBrowser().getName());		// 设备标识
		s.setLoginSystem(ua.getOperatingSystem().getName());	// 系统标识 
		s.setClientDomain(redirect);	// Client端Url 
		s.setClientId(SysClientUtil.getClientIdByUrl(redirect));	// 所属应用id 
		SysLoginLogUtil.sysLoginLogMapper.add(s);
		
		// 更新Session中对象 
		StpUserUtil.getSessionByLoginId(userId).set("user", SysUserAccUtil.getUserById(userId));
    }


    /** 微信与手机号绑定 */
    @Transactional(rollbackFor = Exception.class)
    public int updateOpenId(String phone, String openid, String unionId) {

        // 再查询出来
        int i = sysUserAccMapper.updateOpenId(phone, openid, unionId);
        // 登录成功，返回user对象
        return i ;
    }



}
